package com.yuanjun.product.interceptor;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;


/**
 * @author zsc
 */
@Aspect
@Component
@Slf4j
public class DebuggerAspect {


    @Pointcut("execution(* com.yuanjun.product.controller..*(..)))")
    public void controllerMethodPointcut() {
    }

    @Before("controllerMethodPointcut()")
    public void Interceptor(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        if ("preHandle".equalsIgnoreCase(joinPoint.getSignature().getName())) {
            return;
        }
        log.info("------------------------------------------------------------------------------------------------");
        log.info("请求 URL : {}", request.getRequestURL().toString());
        log.info("请求方法 HTTP_METHOD : {}", request.getMethod());
        log.info("请求 IP : {}", request.getRemoteAddr());
        log.info("方法名 CLASS_METHOD : {}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        Object[] args = joinPoint.getArgs();
        Object[] arguments = new Object[args.length];
        for (int i = 0; i < args.length; i++) {
            if (!(args[i] instanceof ServletRequest) && !(args[i] instanceof ServletResponse) && !(args[i] instanceof MultipartFile)) {
                arguments[i] = args[i];
            }
        }
        log.info("请求参数 ARGS : {}", JSONObject.toJSONString(arguments));
    }

    @AfterReturning(returning = "ret", pointcut = "controllerMethodPointcut()")
    public void doAfterReturning(Object ret) {
        log.info("返回值 : {}", JSONObject.toJSONString(ret));
        log.info("------------------------------------------------------------------------------------------------");
    }

    @Around("controllerMethodPointcut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object ob = pjp.proceed();
        log.info("处理耗时 : {}", (System.currentTimeMillis() - startTime));
        return ob;
    }


}

